#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QLabel>
#include <QTextStream>
#include <QTimer>

#include <ScreenUtils>
#include <ProcInfoUtils.h>
#include <NotificationUtils.h>
#include <qapplication.h>
#include <qcursor.h>
#include <qpoint.h>

MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
    , ui(new Ui::MainWindow)
    , timer(new QTimer(this))
    , procInfo(new ProcInfoUtils)
    , notify(new NotificationUtils("infomation-tips"))
    , workspaceShow(false)
{
    ui->setupUi(this);

    mCpuUsed = ui->mCpuUsed;
    mMemUsed = ui->mMemUsed;
    mNetUpload = ui->mNetUpload;
    mNetDownload = ui->mNetDownload;
    mUptime = ui->mUptime;

    getCpuUsed();
    setAttribute(Qt::WA_TransparentForMouseEvents);
    setAttribute(Qt::WA_TranslucentBackground);
//    setAttribute(Qt::WA_X11BypassTransientForHint);

    setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint| Qt::Tool);
//    setAutoFillBackground(false); //这个不设置的话就背景变黑  -- 无解
//    setWindowOpacity(0);  //0是全透明，1是不透明  窗口及其上面的控件都半透明：
//    setStyleSheet("background-color:transparent;");  //样式表设置透明

    ScreenUtils::moveCenterForCursor(*this);
    m_position = pos();
    timer->setInterval(1000);
    timer->start();

    connect(timer,&QTimer::timeout, this, &MainWindow::onTimerout);

    // 当设置了 Qt::WindowStaysOnTopHint 后，如果切换了工作区，将可能需要 hide()/show() 来显示在新的工作区中。
    // 这里使用定时器，3.5秒刷新一新 hide()/show() 
    showHideTimer = new QTimer;
    showHideTimer->setInterval(3500);
    connect(showHideTimer, &QTimer::timeout, [&](){
        if (workspaceShow) {
            hide();
            show();
        }
    });
    showHideTimer->start();

    trayIcon.setParent(this);
    trayIcon.setIcon(QIcon("://assets/infomation.png"));
    trayIcon.show();

    trayIcon.setContextMenu([this](){
        menu = new QMenu();
        a = menu->addAction("启用工作区切换显示", [this](){
            workspaceShow = true;
            a->setEnabled(false);
            b->setEnabled(true);
            QString message = QString("已启用工作区切换显示");
            notify->sendNotification(message);
        });
        b = menu->addAction("关闭工作区切换显示", [this](){
            workspaceShow = false;
            a->setEnabled(true);
            b->setEnabled(false);
            QString message = QString("已关闭工作区切换显示");
            notify->sendNotification(message);
        });
        b->setEnabled(false);

        menu->addAction("退出", [this](){
            qApp->quit();
        });
        return menu;
    }());
}

QString MainWindow::getCpuUsed()
{
    double percent = procInfo->getLinuxCpuPercent();
    if (percent < 50)
        mCpuUsed->setStyleSheet("QLabel{ color:rgb(79, 158, 57)}");
    if (percent > 50)
        mCpuUsed->setStyleSheet("QLabel{ color:rgb(199, 189, 80)}");
    if (percent > 80)
        mCpuUsed->setStyleSheet("QLabel{ color:rgb(208, 50, 47)}");
    QString result = QString("CPU:%1%").arg(percent, 0, 'f', 2, QLatin1Char(' '));
    
    return result;
}

static double history_percent = 0;
QString MainWindow::getMemUsed()
{
    double percent = procInfo->getLinuxMemPercent().at(0);
   
    if (percent < 50)
        mMemUsed->setStyleSheet("QLabel{ color:rgb(79, 158, 57)}");
    if (percent > 50)
        mMemUsed->setStyleSheet("QLabel{ color:rgb(199, 189, 80)}");
    if (percent > 80)
        mMemUsed->setStyleSheet("QLabel{ color:rgb(208, 50, 47)}");
    
    if (true) {     // TODO：这里应该怎么做呢/如果太频繁发送通知，很影响使用呢

    } else if (percent > 93) {
        // if (history_percent < 93) {
        //     QString message = QString("内存占用已达到临界: %1% -> %2%").arg(history_percent).arg(percent);
        //     notify->sendNotification(message);
        //     history_percent = 93;
        // }
    } else if (percent > 90) {                 // 进入 90% 占用状态
        // if (history_percent < 90) {
            QString message = QString("内存占用已进入临界: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 90;
        // }
    } else if (percent > 85) {          // 进入 85% 占用状态
        if (history_percent < 85) {
            QString message = QString("内存占用已进入极限: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 85;
        } else if (history_percent > 85)  {  // 回退到 85% 占用状态
            QString message = QString("内存占用已低于极限: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 85;
        }
    } else if (percent > 80) {          // 进入 80% 占用状态
        if (history_percent < 80) {
            QString message = QString("内存占用已进入过高负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 80;
        } else if (history_percent > 80) {  // 回退到 80% 占用状态
            QString message = QString("内存占用已低于过高负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 80;
        }
    } else if (percent > 75) {          // 进入 75% 占用状态
        if (history_percent < 75) {
            QString message = QString("内存占用已达到高负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 75;
        } else if (history_percent > 75) {  // 回退到 85% 占用状态
            QString message = QString("内存占用已低于高负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 75;
        }
    } else if (percent > 70) {          // 进入 70% 占用状态
        if (history_percent < 70) {
            QString message = QString("内存占用已进入中负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 70;
        } else if (history_percent > 70) {  // 回退到 80% 占用状态
            QString message = QString("内存占用已低于中负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 70;
        }
    } else if (percent > 60) {          // 进入 60% 占用状态
        if (history_percent < 60) {
            QString message = QString("内存占用已进入低负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 60;
        } else if (history_percent > 60) {  // 回退到 60% 占用状态
            QString message = QString("内存占用已低于低负载: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 60;
        }
    } else if (percent > 50) {          // 进入 50% 占用状态
        if (history_percent < 50) {
            QString message = QString("内存占用已进入一半: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 50;
        } else if (history_percent < 50) {  // 回退到 50% 占用状态
            QString message = QString("内存占用已低于过高: %1% -> %2%").arg(history_percent).arg(percent);
            notify->sendNotification(message);
            history_percent = 50;
        }
    }

    return QString("MEM:%1%").arg(percent, 0, 'f', 2, QLatin1Char(' '));
}

QString MainWindow::getNetUpload()
{
    double upSpeed = 0;
    ProcInfoUtils::SpeedRateUnit unit;

    unit = ProcInfoUtils::SpeedRateByte;
    long upload = procInfo->getLinuxNetworkUp();
    QString uploadUnit = procInfo->autoRateUnits(upload, unit, upSpeed);
//↑:

    return QString("↑:%1").arg(upSpeed, 0, 'f', 2, QLatin1Char(' ')) + uploadUnit;
}

QString MainWindow::getNetDownload()
{
    double downSpeed = 0;
    ProcInfoUtils::SpeedRateUnit unit;

    unit = ProcInfoUtils::SpeedRateByte;
    long download = procInfo->getLinuxNetworkDownload();
    QString downUnit = procInfo->autoRateUnits(download, unit, downSpeed);
//↓:
    return QString("↓:%1").arg(downSpeed, 0, 'f', 2, QLatin1Char(' ')) + downUnit;
}

QString MainWindow::getUptime()
{
    int uptime = procInfo->getLinuxUptime();
    
    int s = 60;
    int m = 60*60;
    int h = 60*60*24;
    int d = 60*60*24;
    int ss =  uptime % s;
    int mm = (uptime % m) / s;
    int hh = (uptime % h) / m;
    int dd = (uptime / d);
    QString runTime = QString("系统已运行: %1天, %2:%3:%4")
            .arg(dd, 0, 'f', 0, QLatin1Char(' '))
            .arg(hh, 2, 'f', 0, QLatin1Char('0'))
            .arg(mm, 2, 'f', 0, QLatin1Char('0'))
            .arg(ss, 2, 'f', 0, QLatin1Char('0'));

    return runTime;
}

void MainWindow::onTimerout()
{

    mCpuUsed->setText(getCpuUsed());
    mMemUsed->setText(getMemUsed());
    mNetUpload->setText(getNetUpload());
    mNetDownload->setText(getNetDownload());
    mUptime->setText(getUptime());

    // 当前鼠标所在屏幕
    auto screen = QApplication::screenAt(QCursor::pos());
    // 当前屏幕矩形所在的象限位置
        // availableGeometry 返回可用屏幕的大小，不包括屏幕下方的工具栏。
        // (但仅只有一个监视器时有效)
    auto s_x = screen->availableGeometry().x();
    auto s_y = screen->availableGeometry().y();
    auto s_w = screen->availableGeometry().width();
    auto s_h = screen->availableGeometry().height();

    // 当前鼠标的位置
    auto c_x = QCursor::pos().x();
    auto c_y = QCursor::pos().y();

    qDebug() << "-----------------";
    qDebug() << "所在屏幕：" << screen;
    qDebug() << "屏幕位置: s_x" << s_x << "s_y" << s_y;
    qDebug() << "屏幕高度: s_w" << s_w << "s_h" << s_h;
    qDebug() << "光标位置: c_x" << c_x << "c_y" << c_y;
    qDebug() << "本体位置: x" << x() << "y" << y();
    qDebug() << "本体高度: w" << width() << "h" << height();
    qDebug() << "矩形位置: x" << rect().x() << "y" << rect().y();
    
    // 鼠标是否与当前显示位置重叠
    mouse_inner = this->geometry().contains(QCursor::pos());;

    m_position.setX(s_x + s_w - width());
    if (mouse_inner || m_position.x() != x()) {
        if (mouse_inner) {
            if (y() == s_y) {
                m_position.setY(s_y + s_h - height());
                top_or_bottom = false;
            } else {
                m_position.setY(s_y);
                top_or_bottom = true;
            }
        } else {
            if (top_or_bottom) {
                m_position.setY(s_y);
            } else {
                m_position.setY(s_y + s_h - height());
            }
        }
    }
    move(m_position);
    qDebug() << "位置: " << m_position;
}
